package lupita.utils;

import java.util.List;

public class PaginatingImpl implements Paginating {

  private List originalList;
  private int pagesize;
  private static final String INVALID_PAGESIZE =
    "Pagesize must be a positive integer.";

  public PaginatingImpl (final List originalList,
    final int pagesize)
  throws IllegalArgumentException {
    if (pagesize <= 0)
      throw new IllegalArgumentException (INVALID_PAGESIZE);
    this.originalList = originalList;
    this.pagesize = pagesize;
  }

  public Page getFirstPage () {
    Page result = null;
    if (originalList != null && originalList.size () > 0) {
      result = new Page (1, getTotalPage(), pagesize,
        iterateFrom (0));
      }
    return result;
  }

  public Page getLastPage () {
    Page result = null;
    if (originalList != null && originalList.size() > 0) {
      final int totalPage = getTotalPage();
      final int startIndex = (totalPage - 1) * pagesize;
      result = new Page (totalPage, totalPage, pagesize,
        iterateFrom (startIndex));
    }
    return result;
  }

  public Page getNextPage (final Page currentPage) {
    if (currentPage == null) return getFirstPage ();
    if (currentPage.isLastPage()) return currentPage;

    Page result = null;
    if (originalList != null) {
      result = new Page (currentPage.getPageNum() + 1,
        currentPage.getTotalPage(),
        pagesize,
        iterateFrom (currentPage.getPageNum() * pagesize));
    }
    return result;
  }

  public Page getPrevPage (final Page currentPage) {
    if (currentPage == null) return getFirstPage ();
    if (currentPage.isFirstPage()) return currentPage;

    Page result = null;
    if (originalList != null) {
      result = new Page (currentPage.getPageNum() - 1,
         currentPage.getTotalPage(),
           pagesize,
        iterateFrom ((currentPage.getPageNum() - 2) *
          pagesize));
    }
    return result;
  }

  private List iterateFrom (final int startIndex) {
    final int totalSize = originalList.size ();

    int endIndex = startIndex + pagesize;
    if (endIndex > totalSize) endIndex = totalSize;

    return originalList.subList (startIndex, endIndex);
  }

  private int getTotalPage () {
    if (originalList == null || originalList.size() <= 0)
      return 0;
    final int totalSize = originalList.size();
    return ((totalSize - 1) / pagesize) + 1;
  }
}
